#include <stdio.h>
#include <string>
#include <thread>
static std::string _CutParenthesesNTail(std::string&& prettyFuncon)
{
    auto pos = prettyFuncon.find('(');
    if(pos!=std::string::npos)
        prettyFuncon.erase(prettyFuncon.begin()+pos, prettyFuncon.end());

    return std::move(prettyFuncon);
}
#define __STR_FUNCTION__ _CutParenthesesNTail(__PRETTY_FUNCTION__).c_str()

#define PRINT1(fmt, ...) printf("%s: " fmt "\n", __func__, ##__VA_ARGS__)
#define PRINT2(fmt, ...) printf("%s: " fmt "\n", __PRETTY_FUNCTION__, ##__VA_ARGS__)
#define PRINT3(fmt, ...) printf("%s: " fmt "\n", __STR_FUNCTION__, ##__VA_ARGS__)

class Object {
public:
    Object(const char *name)
    {
        name_ = name;
        PRINT1("%s", name_);
        PRINT2("%s", name_);
        PRINT3("%s", name_);
    }

    ~Object()
    {
        PRINT1("%s", name_);
        PRINT2("%s", name_);
        PRINT3("%s", name_);
    }

private:
    const char *name_ = nullptr;
};

#include <sstream>
#include <functional>

class Logger : public std::stringstream {
public:
    Logger(const char *file, const char *func, int line, Logger&(*f)(Logger&))
    {
        file_ = file;
        func_ = func;
        line_ = line;
        out = f;
    }

    ~Logger()
    {
        out(*this);
    }

private:
    const char *file_;
    const char *func_;
    int line_;
    Logger&(* out)(Logger&);
};

Logger& Printf(Logger &l)
{
    printf("%s\n", l.str().c_str());
    return l;
}

#define GSLOG(func) Logger(__FILE__, __func__, __LINE__, func)

int main()
{
    GSLOG(Printf) << "3" << 1 << 1.1;

    Object a("a");
    return 0;
}
